home *** CD-ROM | disk | FTP | other *** search
/ Belgian Amiga Club - ADF Collection / BS1 part 43.zip / Sources C- WorkDisk III.adf / vsprite1.c < prev   
C/C++ Source or Header  |  1987-02-16  |  20KB  |  497 lines

  1. /* vsprite.final.c, merged with its support files */
  2. /* execute makesimple vsprite.final ; Amiga C 1.1 (Lattice 3.03) */
  3. #include "exec/types.h"
  4. #include "intuition/intuition.h"
  5. #include "graphics/sprite.h"
  6. #include "exec/memory.h"
  7. #include "graphics/gels.h"
  8. /* ask system to create and manage MAXSP vsprites */
  9. #define MAXSP 28
  10. /* define possible speeds for vsprites in counts per vblank */
  11. SHORT speed[] = { 1, 2, -1, -2 };
  12. SHORT xmove[MAXSP], ymove[MAXSP];
  13.                                 /* sprite directions of movement */
  14. struct VSprite *vsprite[MAXSP]; /* MAXSP simple sprites */
  15. struct VSprite *vspr;           /* pointer to a sprite */
  16. short maxgot;                   /* max # of sprites we created */
  17. struct GelsInfo mygelsinfo;     /* the window's RastPort needs one
  18.                                  * of these in order to do VSprites */
  19. struct Window *w;       /* pointer to a Window   */
  20. struct RastPort *rp;    /* pointer to a RastPort */
  21. struct Screen *s;       /* a pointer to a Screen */
  22. struct ViewPort *vp;    /* pointer to a ViewPort */
  23. struct Window *OpenWindow();
  24. struct Screen *OpenScreen();
  25. LONG GfxBase;
  26. LONG IntuitionBase;
  27. /* 18 words of sprite data = 9 lines of sprite data */
  28. UWORD sprite_data[ ] = {
  29.                         0x0fc3, 0x0000, /* image data line 1*/
  30.                         0x3ff3, 0x0000, /* image data line 2*/
  31.                         0x30c3, 0x0000, /* image data line 3*/
  32.                         0x0000, 0x3c03, /* image data line 4*/
  33.                         0x0000, 0x3fc3, /* image data line 5*/
  34.                         0x0000, 0x03c3, /* image data line 6*/
  35.                         0xc033, 0xc033, /* image data line 7*/
  36.                         0xffc0, 0xffc0, /* image data line 8*/
  37.                         0x3f03, 0x3f03, /* image data line 9*/
  38.                         };
  39. UWORD *sprdata;
  40. movesprites()
  41. {
  42.         short i;
  43.         for (i=0; i<maxgot; i++)
  44.         {
  45.                 vspr = vsprite[i];
  46.                 vspr->X = xmove[i]+vspr->X;
  47.                 vspr->Y = ymove[i]+vspr->Y;
  48.                 /* move the sprites ... here. */
  49.                 if(vspr->X >= 300 || vspr->X <= 0) xmove[i]=-xmove[i];
  50.                 if(vspr->Y >= 190 || vspr->Y <= 0) ymove[i]=-ymove[i];
  51.  
  52.         }
  53.         SortGList(rp);  /* get the list in order */
  54.         DrawGList(rp, vp);      /* create the sprite instructions */
  55.         MakeScreen(s);  /* ask Intuition to pull it all together */
  56.         RethinkDisplay(); /* and to show us what we have now. */
  57. }
  58. #define AZCOLOR 1
  59. #define WHITECOLOR 2
  60. #define WC WINDOWCLOSE
  61. #define WS WINDOWSIZING
  62. #define WDP WINDOWDEPTH
  63. #define WDR WINDOWDRAG
  64. #define NORMALFLAGS (WC|WS|WDP)
  65. /* Did not use windowdrag because dont want screen to be moved. */
  66. /* Allow window sizing so user can decrease size of window, then
  67.  * increase it again, thus erasing the background text and more
  68.  * easily see that some vsprites wink out and into existence when
  69.  * too many sprites are on a single horizontal plane and the
  70.  * vsprite machine runs out of sprites to assign.
  71.  */
  72. /* myfont1 specifies characteristics of the default font;
  73.  * this case selects the 80 column font that displays as
  74.  * 40 columns in low resolution mode.
  75.  */
  76. struct TextAttr myfont1 = { "topaz.font", 8, 0, 0 };
  77.  
  78. struct NewScreen myscreen1 = {
  79.         0, 0,           /* LeftEdge, TopEdge ... where to put screen */
  80.         320, 200,       /* Width, Height ... size of the screen */
  81.         5,              /* 5 planes Depth, means 2 to the 5th or
  82.                         * 32 different colors to choose from once
  83.                         * the screen is opened.
  84.                         */
  85.         1, 0,           /* DetailPen, BlockPen */
  86.         SPRITES,        /* ViewModes ... value of 0 = low resolution */
  87.         CUSTOMSCREEN,   /* Type of screen */
  88.         &myfont1,       /* Font to be used as default for this screen */
  89.         "32 Color Test", /* DefaultTitle for its title bar */
  90.         NULL,           /* screens user-gadgets, always NULL, ignored */
  91.         NULL };
  92.                         /* address of custom bitmap for screen,
  93.                          * not used in this example
  94.                          */
  95. struct NewWindow myWindow = {
  96.         0,              /* LeftEdge for window measured in pixels,
  97.                            at the current horizontal resolution,
  98.                            from the leftmost edge of the Screen */
  99.         0,              /* TopEdge for window is measured in lines
  100.                            from the top of the current Screen.   */
  101.         320, 185,       /* Width, Height of this window */
  102.         0,              /* DetailPen - what pen number is to be
  103.                            used to draw the borders of the window */
  104.         1,              /* BlockPen - what pen number is to be
  105.                            used to draw system generated window
  106.                            gadgets */
  107.                         /* (for DetailPen and BlockPen, the value
  108.                             of -1 says "use the default value")  */
  109.         CLOSEWINDOW,    /* simplesprite program used INTUITICKS also */
  110.                         /* IDCMP Flags */
  111.         NORMALFLAGS | GIMMEZEROZERO | ACTIVATE,
  112.                         /* Window Flags:  (see below for more info) */
  113.         NULL,           /* FirstGadget */
  114.         NULL,           /* CheckMark   */
  115.         "Click Close Gadget To Stop",   /* Window title */
  116.         NULL,           /* Pointer to Screen if not workbench */
  117.         NULL,           /* Pointer to BitMap if a SUPERBITMAP window */
  118.         320, 10,        /* minimum width, minimum height */
  119.         320, 200,       /* maximum width, maximum height */
  120.         CUSTOMSCREEN
  121.         };
  122. #include "graphics/gfxmacros.h"
  123. /* #include "event1.c"  */
  124. /* gets the event handler */
  125. /* event1.c */
  126. HandleEvent(code)
  127.         LONG code;      /* provided by main */
  128. {
  129.         switch(code)
  130.         {
  131.         case CLOSEWINDOW:
  132.                 return(0);
  133.                 break;
  134.         case INTUITICKS:        /* could have done much faster
  135.                                  * but what the heck, this is
  136.                                  * shorter for test purposes
  137.                                  */
  138.                 movesprites();  /* 10 moves per second; test */
  139.                 default:
  140.                         break;
  141.         }
  142. return(1);
  143. }
  144. UWORD mycolortable[] = {
  145.         0x0000, 0x0e30, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
  146.         0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
  147.         0x0fff, 0x0fff, 0x0fff, 0x0fff, 0x0fff,
  148.         0x0fff, 0x0fff, 0x0fff, 0x0fff,
  149.         0x0fff, 0x0fff, 0x0fff, 0x0fff,
  150.         0x0fff, 0x0fff, 0x0ffe, 0x0fff,
  151.         0x0fff, 0x0fff, 0x0fff, 0x0fff
  152.         };
  153. UWORD colorset0[ ] = { 0x0fff, 0x0fff, 0x0fff }; /* same as colors 17-19 */
  154. UWORD colorset1[ ] = { 0x0fff, 0x0fff, 0x0fff }; /* 21-23 */
  155. UWORD colorset2[ ] = { 0x0fff, 0x0fff, 0x0fff }; /* 25-27 */
  156. UWORD colorset3[ ] = { 0x0fff, 0x0fff, 0x0fff }; /* 29-31 */
  157. UWORD *colorset[ ] = {
  158.                         colorset0, colorset1,
  159.                         colorset2, colorset3 };
  160. int choice;
  161. char *numbers[] = { "17","18","19",
  162.                     "20","21","22","23",
  163.                     "24","25","26","27",
  164.                     "28","29","30","31" };
  165. /* #include "ram:purgegels.c" */
  166. /* purgegels.c */
  167. /*
  168.  * Use this to get rid of the gels stuff when it is not needed any more.
  169.  * You must have allocated the gels info stuff (use the ReadyGels routine).
  170.  */
  171. PurgeGels(g)
  172. struct GelsInfo *g;
  173. {
  174.    if (g->collHandler != NULL)
  175.       FreeMem(g->collHandler, sizeof(struct collTable));
  176.    if (g->lastColor != NULL)
  177.       FreeMem(g->lastColor, sizeof(LONG) * 8);
  178.    if (g->nextLine != NULL)
  179.       FreeMem(g->nextLine, sizeof(WORD) * 8);
  180.    if (g->gelHead != NULL)
  181.       FreeMem(g->gelHead, sizeof(struct VSprite));
  182.    if (g->gelTail != NULL)
  183.       FreeMem(g->gelTail, sizeof(struct VSprite));
  184. }
  185. /* Deallocate memory which has been allocated by the routines Makexxx. */
  186. /* Assumes images and imageshadow deallocated elsewhere. */
  187. DeleteGel(v)
  188. struct VSprite *v;
  189. {
  190.    if (v != NULL) {
  191.       if (v->VSBob != NULL) {
  192.          if (v->VSBob->SaveBuffer != NULL) {
  193.             FreeMem(v->VSBob->SaveBuffer, sizeof(SHORT) * v->Width
  194.                   * v->Height * v->Depth);
  195.          }
  196.          if (v->VSBob->DBuffer != NULL) {
  197.             if (v->VSBob->DBuffer->BufBuffer != 0) {
  198.                FreeMem(v->VSBob->DBuffer->BufBuffer,
  199.                      sizeof(SHORT) * v->Width * v->Height * v->Depth);
  200.             }
  201.             FreeMem(v->VSBob->DBuffer, sizeof(struct DBufPacket));
  202.          }
  203.          FreeMem( v->VSBob, sizeof(struct Bob));
  204.       }
  205.       if (v->CollMask != NULL) {
  206.          FreeMem(v->CollMask, sizeof(WORD) * v->Height * v->Width);
  207.       }
  208.       if (v->BorderLine != NULL) {
  209.          FreeMem(v->BorderLine, sizeof(WORD) * v->Width);
  210.       }
  211.       FreeMem(v, sizeof(struct VSprite));
  212.    }
  213. }
  214. /* end of purgegels.c */
  215. /* #include "ram:readygels.c" */
  216. /* readygels.c */
  217. struct VSprite *SpriteHead = NULL;
  218. struct VSprite *SpriteTail = NULL;
  219. void border_dummy()     /* a dummy collision routine */
  220. {
  221.    return;
  222. }
  223. ReadyGels(g, r)
  224. struct RastPort *r;
  225. struct GelsInfo *g;
  226. {
  227.    /* Allocate head and tail of list. */
  228.    if ((SpriteHead = (struct VSprite *)AllocMem(sizeof
  229.          (struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0)
  230.    {
  231.       return(-1);
  232.    }
  233.    if ((SpriteTail = (struct VSprite *)AllocMem(sizeof
  234.          (struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0)
  235.    {
  236.       FreeMem(SpriteHead, sizeof(struct VSprite));
  237.       return(-2);
  238.    }
  239.    g->sprRsrvd = 0xFC;  /* do not use sprites 0 or 1. */
  240.    if ((g->nextLine = (WORD *)AllocMem(sizeof(WORD) * 8,
  241.          MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
  242.    {
  243.       FreeMem(SpriteHead, sizeof(struct VSprite));
  244.       FreeMem(SpriteTail, sizeof(struct VSprite));
  245.       return(-3);
  246.    }
  247.  
  248.   if ((g->lastColor = (WORD **)AllocMem(sizeof(LONG) * 8,
  249.          MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
  250.    {
  251.       FreeMem(g->nextLine,8 * sizeof(WORD));
  252.       FreeMem(SpriteHead, sizeof(struct VSprite));
  253.       FreeMem(SpriteTail, sizeof(struct VSprite));
  254.       return(-4);
  255.    }
  256.   /* Next we prepare a table of pointers to the routines which should
  257.    * be performed when DoCollision senses a collision.  This
  258.    * declaration may not be necessary for a basic vsprite with
  259.    * no collision detection implemented, but then it makes for
  260.    * a complete example.
  261.    */
  262.    if ((g->collHandler = (struct collTable *)AllocMem(sizeof(struct
  263.          collTable), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
  264.    {
  265.       FreeMem(g->lastColor, 8 * sizeof(LONG));
  266.       FreeMem(g->nextLine,8 * sizeof(WORD));
  267.       FreeMem(SpriteHead, sizeof(struct VSprite));
  268.       FreeMem(SpriteTail, sizeof(struct VSprite));
  269.       return(-5);
  270.    }
  271.   /* When any part of the object touches or passes across
  272.    * this boundary, it will cause the boundary collision
  273.    * routine to be called.  This is at smash[0] in the
  274.    * collision handler table and is called only if
  275.    * DoCollision is called.
  276.    */
  277.    g->leftmost = 0;
  278.    g->rightmost = r->BitMap->BytesPerRow * 8 - 1;
  279.    g->topmost = 0;
  280.    g->bottommost = r->BitMap->Rows - 1;
  281.    r->GelsInfo = g;  /* Link together the two structures */
  282.    InitGels(SpriteHead, SpriteTail, g );
  283.   /* Pointers initialized to the dummy sprites which will be
  284.    * used by the system to keep track of the animation system.
  285.    */
  286.    SetCollision(0, border_dummy, g);
  287.    WaitTOF();
  288.    return(0);   /* a return value of 0 says all ok, any
  289.                  * negative value tells you when it failed.
  290.                  * (see the listing as to what the routine
  291.                  * was trying to do... all failures are
  292.                  * due to out of memory conditions).
  293.                  */
  294. }
  295. /* end of readygels.c */
  296. /* #include "ram:MakeVSprite.c" */
  297. /* MakeVSprite.c */
  298. struct VSprite *MakeVSprite(lineheight, image, colorset, x, y,
  299.                                 wordwidth, imagedepth, flags)
  300. SHORT lineheight;       /* How tall is this vsprite? */
  301. WORD *image;            /* Where is the vsprite image data, should be
  302.                            twice as many words as the value of lineheight */
  303. WORD *colorset;         /* Where is the set of three words which describes
  304.                            the colors that this vsprite can take on? */
  305. SHORT x, y;             /* What is its initial onscreen position? */
  306. SHORT wordwidth, imagedepth, flags;
  307. {
  308.    struct VSprite *v;   /* Make a pointer to the vsprite structure which
  309.                            this routine dynamically allocates */
  310.    if ((v = (struct VSprite *)AllocMem(sizeof(struct VSprite),
  311.          MEMF_PUBLIC | MEMF_CLEAR)) == 0)
  312.    {
  313.       return(0);
  314.    }
  315.    v->Flags = flags;    /* Is this a vsprite, not a bob? */
  316.    v->Y = y;            /* Establish initial position relative to */
  317.    v->X = x;            /* the Display coordinates. */
  318.    v->Height = lineheight;      /* The Caller says how high it is. */
  319.    v->Width = wordwidth;   /* A vsprite is always 1 word (16 bits) wide. */
  320.   /* There are two kinds of depth... the depth of the image itself, and the
  321.    * depth of the playfield into which it will be drawn. The image depth
  322.    * says how much data space will be needed to store an image if it's
  323.    * dynamically allocated. The playfield depth establishes how much space
  324.    * will be needed to save and restore the background when a bob is drawn.
  325.    * A vsprite is always 2 planes deep, but if it's being used to make a
  326.    * bob, it may be deeper...
  327.    */
  328.    v->Depth = imagedepth;
  329.   /* Assume that the caller at least has a default boundary collision
  330.    * routine.... bit 1 of this mask is reserved for boundary collision
  331.    * detect during DoCollision(). The only collisions reported will be
  332.    * with the borders. The caller can change all this later.
  333.    */
  334.    v->MeMask = 1;
  335.    v->HitMask = 1;
  336.    v->ImageData = image;        /* Caller says where to find the image. */
  337.   /* Show system where to find a mask which is a squished down version
  338.    * of the vsprite (allows for fast horizontal border collision detect).
  339.    */
  340.    if ((v->BorderLine = (WORD *)AllocMem((sizeof(WORD)*wordwidth),
  341.          MEMF_PUBLIC | MEMF_CLEAR)) == 0)
  342.    {
  343.         FreeMem(v, sizeof(struct VSprite));
  344.         return(0);
  345.    }
  346.   /* Show system where to find the mask which contains a 1 bit for any
  347.    * position in the object in any plane where there is a 1 bit (all planes
  348.    * OR'ed together).
  349.    */
  350.    if ((v->CollMask = (WORD *)AllocMem(sizeof(WORD)*lineheight*wordwidth,
  351.          MEMF_CHIP | MEMF_CLEAR)) == 0)
  352.    {
  353.         FreeMem(v, sizeof(struct VSprite));
  354.         FreeMem(v->BorderLine, wordwidth * sizeof(WORD));
  355.         return(0);
  356.    }
  357.   /* This isn't used for a Bob, just a VSprite. It's where the
  358.    * Caller says where to find the VSprites colors.
  359.    */
  360.    v->SprColors = colorset;
  361.    /* These aren't used for a VSprite, and MakeBob'll do set up for Bob. */
  362.    v->PlanePick  = 0x00;
  363.    v->PlaneOnOff = 0x00;
  364.    InitMasks(v);        /* Create the collMask and borderLine */
  365.    return(v);
  366. }
  367. /* end of MakeVSprite.c */
  368. main()
  369. {
  370.         struct IntuiMessage *msg;
  371.         LONG result;
  372.         SHORT k, j, x, y, error;
  373.         UWORD *src, *dest;      /* for copying sprite data to RAM */
  374.         GfxBase = OpenLibrary("graphics.library",0);
  375.         IntuitionBase = OpenLibrary("intuition.library",0);
  376.         /* (error checking left out for brevity here) */
  377.         s = OpenScreen(&myscreen1);  /* try to open it */
  378.         if(s == 0)
  379.         {
  380.                 printf("Can't open myscreen1\n");
  381.                 exit(10);
  382.         }
  383.         myWindow.Screen = s;    /* say where screen is located */
  384.         ShowTitle(s, FALSE);    /* Dont let screen be dragged down...*/
  385.         w = OpenWindow(&myWindow);
  386.         if(w == 0)
  387.         {
  388.                 printf("Window didn't open!\n");
  389.                 CloseScreen(s);
  390.                 exit(20);
  391.         }
  392.         vp = &(s->ViewPort);
  393.         /* set the colors for this viewport */
  394.         LoadRGB4(vp, &mycolortable[0], 32);
  395.         rp = w->RPort;
  396.                 /* Now wait for a message to arrive from Intuition
  397.                  * (task goes to sleep while waiting for the message)
  398.                  */
  399.         /* Write Text using sprite colors so that demo can show
  400.          * how the vsprite machine stuffs the colors as it goes
  401.          * down the screen.  Thus if using vsprites, user should
  402.          * avoid using the color registers that the vsprites use.
  403.          */
  404.         /* Notice also that color numbers 17-19 are untouched.
  405.          * That is because of the sprResrvd=0xFC in ReadyGels.
  406.          * (Doesn't allow the virtual sprite machine to access
  407.          * either sprite 0 or 1... 0 is used by mouse cursor and
  408.          * shares its colors with 1, so I reserved both of them.
  409.          */
  410.         for(j=8; j<180; j+=50)
  411.         {
  412.                 for(k=0; k<15; k++)
  413.                 {
  414.                         Move(rp,k*20,j);
  415.                         SetAPen(rp,k+17);       /* show 17-31 */
  416.                         /* 16, 20, 24, 28 are unaffected by vsprites
  417.                          * because they are not used by hardware sprites */
  418.                         Text(rp,numbers[k],2);
  419.                 }
  420.         }
  421.         /* *************************************** */
  422.         /* VSPRITE DEMO SECTION                    */
  423.         /* *************************************** */
  424.         /* Allocate CHIP memory to hold the actual sprite data */
  425.         /* (necessary if ever to run on an expanded RAM Amiga) */
  426.         sprdata = (UWORD *)AllocMem(36, MEMF_CHIP);
  427.         if(sprdata == NULL)
  428.         {
  429.                 /* not enough memory for sprite */
  430.         }
  431.         /* now copy the sprite data into the CHIP RAM. */
  432.         src = sprite_data;
  433.         dest = sprdata;         /* source, destination */
  434.         for( j=0; j<18; j++)
  435.         {
  436.                 *dest++ = *src++;
  437.         }
  438.         choice = 0;
  439.         maxgot = 0;
  440.         /* Prepare the GELS system to work with VSPRITE or BOBS */
  441.         error = ReadyGels(&mygelsinfo, rp);
  442.         for(k=0; k<MAXSP; k++)  /* whatever maximum number of vsprites */
  443.         {
  444.                 xmove[k]=speed[RangeRand(4)];
  445.                 ymove[k]=speed[RangeRand(4)];
  446.                 /* establish a position for the sprite */
  447.                 x = 10 + RangeRand(280);
  448.                 y = 10 + RangeRand(170);
  449.                 /* create a vsprite */
  450.                 vsprite[k] = MakeVSprite( 9, sprdata, colorset[choice],
  451.                                         x, y, 1, 2, VSPRITE);
  452.                 /* 9 lines high, using MEMF_CHIP image of a sprite,
  453.                  * with a particular set of colors, at an X,Y location
  454.                  * 1 word wide, 2 planes deep (all vsprites are 2 deep)
  455.                  * and it is a VSPRITE */
  456.                 if(vsprite[k] == 0)
  457.                 {
  458.                         break;  /* ran out of memory! */
  459.                 }
  460.                 AddVSprite(vsprite[k], rp);
  461.                 maxgot++;
  462.                 choice++; /* choose a different color set */
  463.                 if(choice >= 4)
  464.                 {
  465.                         choice = 0;     /* wrap around on colorsets */
  466.                 }
  467.         }
  468.         while(1)        /* forever */
  469.         {
  470.                 WaitTOF();
  471.                 movesprites();
  472.                 result = -1;    /* now see if CLOSEWINDOW is waiting */
  473.                 msg = (struct IntuiMessage *)GetMsg(w->UserPort);
  474.                 if(msg != 0)
  475.                 {
  476.                         result = HandleEvent(msg->Class);
  477.                         /* Let Intuition reuse the msg */
  478.                         ReplyMsg(msg);
  479.                 }
  480.                 if(result == 0)
  481.                 {
  482.                         break;  /* got a CLOSEWINDOW */
  483.                 }
  484.         }
  485.         /* DONE, now cleanup */
  486.         /* Free however many vsprites we actually managed to create */
  487.         for(k=0; k<maxgot; k++)
  488.         {
  489.                 DeleteGel(vsprite[k]);
  490.         }
  491.         /* delete what ReadyGels created */
  492.         PurgeGels(&mygelsinfo);
  493.         FreeMem(sprdata, 36);   /* free what we allocated. */
  494.         CloseWindow(w);
  495.         CloseScreen(s);
  496. }
  497.